/**
 * @author maulin
 */
dojo.provide("medryx.orm.tests.ManagedPropertyTests");
dojo.require("doh.runner");
dojo.require("doh.TestCase");
dojo.require("medryx.orm.EntityManager");
dojo.require("medryx.orm.Identifier");
dojo.require("medryx.orm.Property");
dojo.require("medryx.orm.Association");
dojo.require("medryx.orm.Collection");
dojo.require("medryx.exceptions.NullIdentifier");
dojo.require("medryx.orm.PersistenceService")
dojo.require("medryx.orm.tests.support.MockPersistenceService");

dojo.declare("ManagedPropertyTestClass", null, {
	id:new medryx.orm.Identifier(),
	value:new medryx.orm.Property()
});


dojo.declare("ManagedPropertyTestCase", doh.TestCase, {
	setUp:function() {
		this.entity = new ManagedPropertyTestClass();
		this.PersistenceService = new MockPersistenceService();
		this.entityManager = new medryx.orm.EntityManager(this.PersistenceService);
		this.entityManager.registerClass("ManagedPropertyTestClass", null, this.PersistenceService);
	}
});
dojo.declare("ManagedPropertyAsyncTestCase", doh.AsyncTestCase, {
    setUp:function() {
        this.entity = new ManagedPropertyTestClass();
         this.PersistenceService = new MockPersistenceService();
		this.entityManager = new medryx.orm.EntityManager(this.PersistenceService);
       
        this.entityManager.registerClass("ManagedPropertyTestClass", null, this.PersistenceService);
    }
});

doh.register("medryx.orm.tests.ManagedPropertyTests", [
    new ManagedPropertyTestCase("testNullIdentifier", function() {
		var id = new medryx.orm.Identifier({
			identifierGenerator: {
				generateIdentifier: function(){
					return "TESTID";
				}
			}
		});
		
		
		id.initialize(entity, "id", null);
		assertEqual("TESTID", entity.id);
		 
	}),
    new ManagedPropertyTestCase("testInitializePropertyWithConverter", function() {
		var converter = {
			fromPropertyToString:function() {
				
			},
			fromStringToProperty:function(strValue, entity, propertyName) {
				return "[" + strValue + "]";
			}
		}
		var prop = new medryx.orm.Property({converter:converter});
		prop.initialize(entity, "property", "VALUE");
		assertEqual("[VALUE]", entity.property);
	}),
	 new ManagedPropertyTestCase("testInitializePropertyWithoutConverter", function() {
        var prop = new medryx.orm.Property();
        prop.initialize(entity, "property", "TEST VALUE");
		assertEqual("TEST VALUE", entity.property);
    }),
	 new ManagedPropertyTestCase("testInitializeAssociationNull", function() {
        var prop = new medryx.orm.Association({
			associationClass: ManagedPropertyTestClass
		});
        prop.initialize(entity, "property", null);
        assertNull(entity.property);
    }),
     new ManagedPropertyTestCase("testInitializeAssociationEmpty", function() {
        var prop = new medryx.orm.Association({
            associationClass: ManagedPropertyTestClass
        });
        prop.initialize(entity, "property");
        assertInstanceOf(entity.property, medryx.orm.Association);
    }),
	new ManagedPropertyTestCase("testInitializeAssociationId", function() {
        var prop = new medryx.orm.Association({associationClass:"ManagedPropertyTestClass", entityManager:entityManager});
        prop.initialize(entity, "property", 1);
        assertInstanceOf(entity.property, ManagedPropertyTestClass);
		assertEqual(1, entity.property.id);
    }),
	new ManagedPropertyTestCase("testInitializeAssociation", function() {
        var prop = new medryx.orm.Association({associationClass:"ManagedPropertyTestClass", entityManager:entityManager});
        prop.initialize(entity, "property", {id:2, value:"TEST"}, entityManager);
        assertInstanceOf(entity.property, ManagedPropertyTestClass);
		assertEqual(2, entity.property.id);
		assertEqual("TEST", entity.property.value);
    }),
	 new ManagedPropertyTestCase("testInitializeCollectionNull", function() {
        var prop = new medryx.orm.Collection({associationClass:ManagedPropertyTestClass});
        prop.initialize(entity, "property", null);
        assertEqual(0, entity.property.length);
    }),
	 new ManagedPropertyTestCase("testInitializeCollectionEmpty", function() {
        var prop = new medryx.orm.Collection({associationClass:ManagedPropertyTestClass});
        prop.initialize(entity, "property");
        assertInstanceOf(entity.property, medryx.orm.Collection);
    }),
	 new ManagedPropertyTestCase("testInitializeCollectionArrayOfIds", function() {
        var prop = new medryx.orm.Collection({associationClass:"ManagedPropertyTestClass", entityManager:entityManager});
        prop.initialize(entity, "property", [2, 3, 5]);
		assertEqual(3, entity.property.length);
		assertEqual(2, entity.property[0].id);
		 assertInstanceOf(entity.property[0], ManagedPropertyTestClass);
		assertEqual(3, entity.property[1].id);
		 assertInstanceOf(entity.property[1], ManagedPropertyTestClass);
		assertEqual(5, entity.property[2].id);
		 assertInstanceOf(entity.property[2], ManagedPropertyTestClass);
    }),
	new ManagedPropertyTestCase("testInitializeCollectionStringOfIds", function() {
        var prop = new medryx.orm.Collection({associationClass:"ManagedPropertyTestClass", entityManager:entityManager});
        prop.initialize(entity, "property", "2, 3, 5");
		assertEqual(3, entity.property.length);
		assertEqual(2, entity.property[0].id);
		 assertInstanceOf(entity.property[0], ManagedPropertyTestClass);
		assertEqual(3, entity.property[1].id);
		 assertInstanceOf(entity.property[1], ManagedPropertyTestClass);
		assertEqual(5, entity.property[2].id);
		 assertInstanceOf(entity.property[2], ManagedPropertyTestClass);
    }),
	new ManagedPropertyAsyncTestCase("testLoadValueAsync", function() {
	
		entityManager.registerClass("ManagedPropertyTestClass");
        var entity = entityManager.buildEntity("ManagedPropertyTestClass", 10);	
		var prop = entity.value;	
		this.entity = entity; //make it available in the callback scope as well
       PersistenceService.loadResults = {id:10, value:"TEST2"};
		return prop.loadValueDeferred(entity, "value");
    }, function(value) {
		assertEqual("TEST2", entity.value, "the value should be set on the entity");
		assertEqual("TEST2", value, "the value should be returned");
	})
]);
